import webapp2
import jinja2
import os
import datetime
import logging

from google.appengine.api import taskqueue
from google.appengine.api import users
from google.appengine.ext import ndb


JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)


'''
Send mail, when status changes
'''


def loadAllCheckFromDataStore():
    pass
    
    
class NDBProject(ndb.Model):
    name = ndb.StringProperty()
    email = ndb.StringProperty()
    description = ndb.StringProperty()

class NDBRegExChecking(ndb.Model):
  regex = ndb.StringProperty()
  resultCode = ndb.IntegerProperty()
  
class NDBCheck(ndb.Model):
  description = ndb.StringProperty()
  succes = ndb.BooleanProperty()


def fillDatastoreForUser ( inUserEmail ):
    checkList = loadCheckList()
    user = users.get_current_user()  
    
    project = NDBProject( username=user.email, name="default", description="default description" )


checkList = None
def loadCheckList():
    global checkList
    if checkList != None:
        return checkList
    dmtWmsCheck = "http://gdi.vito.be/dmt/lcdwms_v10/map?LAYERS=ScheldeOnTheFly&TRANSPARENT=true&TILED=true&SLD=http%3A%2F%2Fgdi.vito.be%2Fdmt%2Flcdwms_v10%2FData%2Fsld%2FDMT_COLORS.sld&STYLES=DMT_COLORS_1&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fpng&SRS=EPSG%3A900913&BBOX=313086.407,6692215.038425,352222.165475,6731350.7969&WIDTH=256&HEIGHT=256"
    checkList = { 'checkings': [   
                    [ 0,RegularExpressionCheck(".*", dmtWmsCheck, 200 ), [] ],
                    [ 1,RegularExpressionCheck("DMT", "http://gdi.vito.be/DMT/gui_dmt.html", 200 ), [] ],
                    [ 2,RegularExpressionCheck(".*", "http://gdi.vito.be", 200), [] ],
                    [ 3,RegularExpressionCheck("Cosy", "http://gdi.vito.be/redmine",200),  [] ],                                      
                    [ 4,RegularExpressionCheck(".*ADASCIS.*", "http://gdi.vito.be/adascis/adascis_portal.html", 200 ), [] ],
                    [ 5,RegularExpressionCheck("[{\"year\":2008},{\"year\":2009}]", "http://gdi.vito.be/adascis/resources/distinctyear", 200 ),  [] ],
                    [ 6,RegularExpressionCheck(".*ASIS.*", "http://gdi.vito.be/asis/proto_site/", 200 ), [] ],
                    
                ] }
    '''
    checkList = { 'checkings': [   
                    [ RegularExpressionCheck("DMT", "http://gdi.vito.be/DMT/gui_dmt.html", 200 ), [] ]        
                ] }
    '''
    #checkList = [ checkList[1] ]
    return checkList



'''
Responsibility:
    1 Call an url 
    2 return the response code and the response text to callback function
    3 report error to special callback function
    
Collaborators:
    1 google.appengine.api.urlfetch
'''
class UrlToTextResolver():
    
    from google.appengine.api import urlfetch
    
    def __init__ (self):
        logging.info( "creating instance urlresolver" )
        
    def fetchUrl(self, inUrl, inHandler, inErrorHandler):
        try:
            logging.info ( "Gonna call url [%s]" % inUrl )
            result = self.urlfetch.fetch( inUrl )
            logging.debug ( "Result [%s]" % result )
            logging.info( "Gonna call handler from UrlToTextResolver" )
            inHandler( result.status_code, result.content )
            logging.info( "Finished handling UrlToTextResolver" )
        except Exception, e:
            logging.info( str(e) )
            inErrorHandler( str(e) )            

   
'''
Responsibility:
    1 For a given url, check resultcode and regularexpression in result
    2 Feed the given ReportBuilder with the result and comment
Collaborators:
    1 UrlToTextResolver to fetch the Url
    2 CallBack handler for the UrlToTextResolver to report result to the ReportBuilder
'''
class RegularExpressionCheck():

    import re

    url = None
    resultCode = 200
    regex = None

    def __init__( self, inRegularExpr, inUrl, inResultCode ):
        self.url = inUrl
        self.regex = inRegularExpr
        self.resultCode = inResultCode
        logging.info( "Creating reg expcheck [" + inRegularExpr + "]" )


    def createHandlerForErrorCallBack( self, inReportBuilder ):
        
        def handleFetchError( inMessage ):
            logging.info( "Fetch did not succeed" )
            
            if inReportBuilder == None:
                logging.warning( "No reportbuilder, not handling error[%s]" % inMessage )
            else:     
                current_time = datetime.datetime.now()
                inReportBuilder.registerResult ( self.url, "[%s] [%s]" % (current_time.strftime( "%j-%Y:%X" ),inMessage), False )
        
        return handleFetchError

    def createHandlerForCallBack( self, inReportBuilder ):
        
        def handleFetchResult( inCode, inResult ):
            logging.info( "ResultCode [%s] " % inCode )
            
            if inReportBuilder == None:
                logging.warning( "No reportbuilder, not handling result" )
            else:
                isResultCodeSame    = ( inCode == self.resultCode )
                isRegExpFound       = self.re.search( self.regex, inResult ) != None
                
                current_time = datetime.datetime.now()
                theMessage = ( "[%s] Result code OK? [%s], Regular expression check OK? [%s]" ) % ( current_time.strftime( "%j-%Y:%X" ), str(isResultCodeSame), str(isRegExpFound) )
                inReportBuilder.registerResult ( self.url, theMessage, ( isResultCodeSame and isRegExpFound ) )
        
        return handleFetchResult
            
    def check(self, inUrlResolver, inReportBuilder ):
        logging.info( "Gonna check [%s]" % self.url )
        inUrlResolver.fetchUrl( self.url, self.createHandlerForCallBack( inReportBuilder ),  self.createHandlerForErrorCallBack( inReportBuilder )  )        
        logging.info( "Done checking [%s]" % self.url )




'''
Responsibilities:
    1 Put the "Checker"'s endpoint on the queue.
Collaborators:
    1 google.appengine.api.taskqueue
'''
class QueueChecker(webapp2.RequestHandler):
    def get(self):
        logging.info( "Queue queue queue checker" )
        taskqueue.add(url='/checkall')


'''
Responsibilities:
    1 Load all the "Check" objects
    2 Make them check against an UrlResolver
    3 Provide result report builder
Collaborators:
    1 For now, load them from vector in memory
    2 UrlToTextResolver is used
    3 MyRegisterResult updates the intertal in memory vector of check objects    
'''
class Checker(webapp2.RequestHandler):
    
    class MyRegisterResult():
        
        def __init__( self, inCheck ):
            self.check = inCheck
        
        def registerResult( self, inUrl, inDescription, inSucces ):
                logging.info( "registering result" )                
                self.check[2].insert( 0, [ inDescription, inSucces ] )                
                logging.info( "done registering result" )
        
        
    
    def get(self):
        logging.info( "Gonna check all" )
        theRegisterCallBack = None
        try:
            theUrlResolver = UrlToTextResolver()
            theCheckList = loadCheckList()['checkings']
            for theCheck in theCheckList:
                theRegisterCallBack = Checker.MyRegisterResult( theCheck )
                theCheck[1].check( theUrlResolver, theRegisterCallBack )
        except Exception, e:
            theRegisterCallBack.registerResult( None, str(e), False )
            raise e
    
    def post(self):
        self.get()


'''
Responsibilities
    1 Visualize the result
Collaborators
    1 Jinja framework
'''
class MainPage(webapp2.RequestHandler):
    
    def get(self):
              
        template = JINJA_ENVIRONMENT.get_template('results.html')
        checks = loadCheckList()
        self.response.write(template.render(checks))

class CheckDetailsPage(webapp2.RequestHandler):
    
    def get(self, inDetailIndex):        
        template = JINJA_ENVIRONMENT.get_template('checkdetails.html')
        checks = loadCheckList()        
        self.response.write(template.render( { 'details': checks['checkings'][int(inDetailIndex)] } ))


application = webapp2.WSGIApplication([     ('/', MainPage),
                                            ('/checkall', Checker),
                                            ('/details/(\d+)', CheckDetailsPage),
                                            ('/queuechecks', QueueChecker)], debug=True) 
                                            
                                            
'''

class MainPageWithCheck(webapp2.RequestHandler):

    def get(self):
        
        self.response.headers['Content-Type'] = 'text/html'                
        theReportBuilderHtml = ReportBuilderHtml()
                        
        try:
            theUrlResolver = UrlToTextResolver()
            theCheckList = loadCheckList()['checkings']
            for theCheck in theCheckList:
                theCheck[0].check( theUrlResolver, theReportBuilderHtml )
        except Exception, e:
            raise e            
            
        theReportBuilderHtml.dumpToTable( self.response )




class ReportMailGenerator():
        
    urlDescriptionVector = []
    
    def registerResult( self,inUrl,inDescription,inSucces ):
        self.urlDescriptionVector.append( [inUrl,inDescription,inSucces] )
    
    
    
    def dumpToTable( self, inResponse ):
        inResponse.write( "<!DOCTYPE html>\n" )
        inResponse.write( "<html>" )
        
        inResponse.write( "<head>" )
        self.writeStyle( inResponse )
        inResponse.write( "</head>" )
        inResponse.write( "<body>" )
        inResponse.write( "<table>" )
        for theDesc in self.urlDescriptionVector:
                if theDesc[2] == True:
                    inResponse.write( "<tr class='succes'>" )
                else:
                    inResponse.write( "<tr class='failure'>" )
                                    
                inResponse.write( "<td>" )
                inResponse.write( theDesc[0] )                
                inResponse.write( "</td>" )
                inResponse.write( "<td>" )
                inResponse.write( theDesc[1] )                
                inResponse.write( "</td>" )
                inResponse.write( "</tr>" )
        inResponse.write( "</table>" )
        inResponse.write( "</body>" )
        inResponse.write( "</html>" )

    def writeStyle( self, inResponse ):
        theStyleContent = "tr.failure { background-color: red; } tr.succes { background-color: green; } " 
        theStyleDefinition = "<style type='text/css'>%s</style>" % theStyleContent
        inResponse.write( theStyleDefinition )




'''
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            